import { GameRouteData, routeApiConfig } from "js/core/localApi";
import mongodbHandle from "./mongodbHandle"
import app from "src/app";
var ObjectId = require('mongodb').ObjectId;
import moment = require('moment');
import Random from "js/core/random";
import route from "js/route/route";
import configFile from '../config';
import redisHandle from "./redisHandle";
// import * as datefns from 'date-fns';
import sessionHandle from "./sessionHandle";
import routes from "src/route/route";

if (process.argv.length >= 2 && configFile[process.argv[2]]) {
    app.env = process.argv[2]
    app.config = configFile[process.argv[2]]
} else {
    app.env = 'dev'
    app.config = configFile['dev']
}

class PlayerSessionHandle {
    players: any
    playerAmount: number
    constructor() {
        this.players = {}
        this.playerAmount = 0
    }
    init = async () => {


        routeApiConfig.isClient = false
        await redisHandle.init('playerSessionHandle')
        await mongodbHandle.init('playerSessionHandle')
        process.on('message', async (msg) => {
            // console.log("PlayerSessionHandle", msg, route)
            let url = msg.url
            let session = await sessionHandle.getSession(msg.sessionKey)
            if (!session) {
                if (msg.messageID) {
                    process.send({ messageID: msg.messageID, data: { err: 101, code: 0 } })
                }
                return
            }
            if (url == "route") {
                let data = playerSessionHandle.getPlayer(session.pID)
                if (!data) {
                    data = await playerSessionHandle.addPlayer(session.pID)
                }
                if (data) {
                    let date = new Date()
                    let time = date.getTime()
                    let player = data.data.playerData
                    data.version = app.version
                    let dayTime = moment().startOf('day').valueOf()
                    let gameRouteData: GameRouteData = {
                        player: player,
                        random: new Random(msg.data?.s || 25258),
                        time: (msg.data?.t || time), dayTime,
                        version: app.version
                    }
                    try {
                        if (msg.data.fName == 'getMail') {
                            let data = msg.data.data[0]
                            if (!data._id) {
                                process.send({ messageID: msg.messageID, data: { err: 120, code: 0 } })
                            } else {
                                let giftMail = await mongodbHandle.playerAndGiftDao.findOne({ mailID: data._id, read: false })
                                if (!giftMail) {
                                    process.send({ messageID: msg.messageID, data: { err: 120, code: 0 } })
                                } else {
                                    let time = moment().startOf('day').valueOf()
                                    await mongodbHandle.playerAndGiftDao.updateOne({ _id: giftMail._id }, {
                                        $set: {
                                            read: true,
                                            readTime: time,
                                        }
                                    })

                                    let { err } = await route[msg.data.rName][msg.data.fName](...msg.data.data, gameRouteData)
                                    await mongodbHandle.playerDao.updateOne({
                                        _id: ObjectId(session.pID),
                                    }, {
                                        $set: {
                                            playerData: player,
                                            loginTime: new Date().getTime(),
                                        }
                                    })
                                    process.send({ messageID: msg.messageID, data: { err } })
                                }
                            }
                        } else {
                            let { err } = await route[msg.data.rName][msg.data.fName](...msg.data.data, gameRouteData)
                            this.players[session.pID].amount += 1
                            this.players[session.pID].isSave = false
                            if (this.players[session.pID].amount >= 10 || 1) {
                                this.players[session.pID].amount = 0
                                this.players[session.pID].isSave = true

                                let doc = await mongodbHandle.playerDao.findOne({ _id: ObjectId(session.pID) })

                                let mapProgressMax = doc.mapProgressMax || 0
                                if (player && player.baseInfo) {
                                    mapProgressMax = player.baseInfo.mapProgressMax
                                }

                                if (doc.chargeMoney > player.baseInfo.chargeMoney) {
                                    player.baseInfo.chargeMoney = doc.chargeMoney
                                }
                                let totalPower = doc.totalPower || 0
                                if (player.totalPower) {
                                    totalPower = player.totalPower
                                }
                                let deepProgress = doc.deepProgress || 0
                                if (player.deepInfo) {
                                    deepProgress = player.deepInfo.progress
                                }
                                let nightProgress = doc.nightProgress || 0
                                if (player.deepInfo.nightProgress) {
                                    nightProgress = player.deepInfo.nightProgress
                                }
                                let itemInfo = doc.itemInfo || {}
                                if (player.itemInfo) {
                                    itemInfo = player.itemInfo
                                }

                                let booming = doc.booming || 0
                                if (player.townInfo && player.townInfo.booming) {
                                    booming = player.townInfo.booming
                                }
                                let weekDay = Math.floor((moment().startOf('day').valueOf() - 1686412800000) / (7 * 24 * 60 * 60 * 1000))
                                await mongodbHandle.playerDao.updateOne({
                                    _id: ObjectId(session.pID),
                                }, {
                                    $set: {
                                        totalPower,
                                        mapProgressMax,
                                        deepProgress,
                                        nightProgress,
                                        weekDayIndex: weekDay,
                                        booming,
                                        itemInfo: player.itemInfo,
                                        playerData: player,
                                        loginTime: new Date().getTime(),
                                    }
                                })
                            }
                            // this.players[session.pID].amount = 0
                            //     this.players[session.pID].isSave = true
                            //     await mongodbHandle.playerDao.updateOne({
                            //         _id: ObjectId(session.pID),
                            //         cheat: false,
                            //     }, {
                            //         $set: {
                            //             playerData: player,
                            //             loginTime: new Date().getTime(),
                            //         }
                            //     })
                            process.send({ messageID: msg.messageID, data: { err } })
                        }
                    } catch (e) {
                        console.log(e)
                        process.send({ messageID: msg.messageID, data: { err: 120, code: 0 } })
                    }
                }
            } else {
                let loginRoute = routes.login[url];
                if (loginRoute) {
                    let { err, data, code } = await loginRoute(msg.data, session)
                    if (msg.messageID) {
                        process.send({ messageID: msg.messageID, data: { err, data, code } })
                    }
                }
            }
        })
        setInterval(() => {
            this.updatePlayer()
        }, 2 * 60 * 1000)

    }
    addPlayer = async (pID) => {
        if (!this.players[pID]) {
            this.playerAmount += 1
        }
        let res = await mongodbHandle.playerDao.findOne({ _id: ObjectId(pID) })
        if (res) {
            this.players[pID] = { data: res, time: new Date().getTime(), amount: 0, isSave: true }
            return this.players[pID]
        }
    }
    getPlayer = (pID) => {
        return this.players[pID]
    }

    savePlayer = async (pID) => {
        let data = this.players[pID]
        if (data && data.isSave == false) {
            let playerData = data.data
            await mongodbHandle.playerDao.updateOne({
                _id: ObjectId(pID),
            }, {
                $set: {
                    playerData: playerData.playerData,
                    loginTime: new Date().getTime(),
                }
            })
            data.isSave = true
            data.amount = 0
            data.time = new Date().getTime()
        }
    }

    deleteByPID = (pID) => {
        delete this.players[pID]
        this.playerAmount -= 1
    }

    async updatePlayer() {
        let playerAmount = 0
        let pIDs = []
        for (let [pID, data] of Object.entries(this.players)) {
            let _data = data as any
            let time = _data.time
            if (_data.isSave == false) {
                let playerData = _data.data
                await mongodbHandle.playerDao.updateOne({
                    _id: ObjectId(pID),
                    cheat: false
                }, {
                    $set: {
                        playerData: playerData.playerData,
                        loginTime: new Date().getTime(),
                    }
                })
                _data.isSave = true
                _data.amount = 0
            }
            let now = new Date().getTime()
            if (now - time > 30 * 60 * 60 * 24) {
                this.deleteByPID(pID)
                pIDs.push(pID)
            } else {
                playerAmount += 1

            }
        }
        process.send({ message: "playerAmount", playerAmount, forkID: app.forkID, pIDs: pIDs })
    }

}



let playerSessionHandle = new PlayerSessionHandle()
export default playerSessionHandle